package com.farm.view.model.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ConnectException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.farm.core.config.CmdConfig;
import com.farm.parameter.FarmParameterService;

public class OpenOffceUtils {
	private static final Logger log = Logger.getLogger(OpenOffceUtils.class);
	private static String SERVER_IP = FarmParameterService.getInstance().getParameter("config.openoffice.host");
	private static String CMD_ENCODE = FarmParameterService.getInstance().getParameter("config.server.os.cmd.encode");
	private static int SERVER_PORT = FarmParameterService.getInstance().getParameterInt("config.openoffice.port");
	private static String START_WIN_CMD = CmdConfig.getCmd("config.cmd.openoffice.win.start");
	private static String KILL_WIN_CMD = CmdConfig.getCmd("config.cmd.openoffice.win.kill");
	private static String START_LINUX_CMD = CmdConfig.getCmd("config.cmd.openoffice.linux.start");
	private static String KILL_LINUX_CMD = CmdConfig.getCmd("config.cmd.openoffice.linux.kill");
	private static boolean IS_LINUX = FarmParameterService.getInstance()
			.getParameterBoolean("config.server.os.islinux");

	/**
	 * 获得openoffcie服务链接失败后会重启openoffice，再链接一次（使用完成后必须关闭链接）
	 * 
	 * @return
	 * @throws ConnectException
	 */
	public static OpenOfficeConnection openConnection() throws ConnectException {
		if (!isStart()) {
			reStart();
		}
		// 创建Openoffice连接
		OpenOfficeConnection con = new SocketOpenOfficeConnection(SERVER_IP, SERVER_PORT);
		try {
			con.connect();
		} catch (ConnectException e) {

		}
		return con;
	}

	/**
	 * openoffce服务是否启动
	 * 
	 * @return
	 */
	public static boolean isStart() {
		// 超過3秒連不上就認爲是服務死掉了
		long outTime = 3000;
		ExecutorService executor = Executors.newSingleThreadExecutor();
		FutureTask<Boolean> future = new FutureTask<Boolean>(new Callable<Boolean>() {
			@Override
			public Boolean call() throws Exception {
				boolean isStart = false;
				OpenOfficeConnection con = new SocketOpenOfficeConnection(SERVER_IP, Integer.valueOf(SERVER_PORT));
				try {
					con.connect();
					if (con.isConnected()) {
						isStart = true;
					} else {
						isStart = false;
					}
				} catch (ConnectException e1) {
					isStart = false;
				} finally {
					if (isStart) {
						con.disconnect();
					}
				}
				return isStart;
			}
		});
		executor.execute(future);
		boolean isStart = false;
		try {
			// 在一定时间内执行该任务
			isStart = future.get(outTime, TimeUnit.MILLISECONDS); // 取得结果，同时设置超时执行时间为5秒。同样可以用future.get()，不设置执行超时时间取得结果
		} catch (Exception e) {
			future.cancel(true);
		} finally {
			executor.shutdown();
		}
		return isStart;
	}

	/**
	 * 启动office转换服务(相当于重启，先杀掉进程再启动进程)
	 */
	public static void reStart() {
		shutdown();
		try {
			Runtime runtime = Runtime.getRuntime();
			log.info("run[start]---openoffice service...");

			if (IS_LINUX) {
				log.info("is linux run cmd:" + START_LINUX_CMD);
				String[] linuxcmd = new String[] { "sh", "-c", START_LINUX_CMD };
				runtime.exec(linuxcmd);
			} else {
				log.info("is windows run cmd:" + START_WIN_CMD);
				runtime.exec(START_WIN_CMD);
			}
		} catch (IOException exception) {
			log.error("Error:run[start]---openoffice service:" + exception.getMessage(), exception);
		}
	}

	public static void shutdown() {
		try {
			Runtime runtime = Runtime.getRuntime();
			log.info("run[kill]---openoffice service...");
			Process proc1 = null;
			if (IS_LINUX) {
				log.info("is linux run cmd:" + KILL_LINUX_CMD);
				String[] linuxcmd = new String[] { "sh", "-c", KILL_LINUX_CMD };
				proc1 = runtime.exec(linuxcmd);
			} else {
				log.info("is windows run cmd:" + KILL_WIN_CMD);
				proc1 = runtime.exec(KILL_WIN_CMD);
			}
			BufferedReader br = new BufferedReader(new InputStreamReader(proc1.getInputStream(), CMD_ENCODE));
			String msg = null;
			while ((msg = br.readLine()) != null) {
				log.info(msg);
			}
		} catch (IOException exception) {
			log.error("Error:run[kill]---openoffice service:" + exception.getMessage(), exception);
		}
	}

}
